package io.github.fan0424.composedemo1

import android.content.Intent
import android.os.Bundle
import android.util.Log
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.animation.core.*
import androidx.compose.foundation.Image
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.*
import androidx.compose.material.Text
import androidx.compose.runtime.*
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.draw.drawBehind
import androidx.compose.ui.draw.drawWithCache
import androidx.compose.ui.draw.drawWithContent
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.Path
import androidx.compose.ui.layout.Layout
import androidx.compose.ui.layout.Placeable
import androidx.compose.ui.layout.layout
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.*
import java.util.ArrayList
import kotlin.math.max
import kotlin.math.roundToInt

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        var testText by mutableStateOf("abc")

        val nums = mutableStateListOf(1, 2, 3)
        var testRef = 1

        var anim1 by mutableStateOf(false)
        var anim2 by mutableStateOf(false)
        var anim3 by mutableStateOf(false)
        setContent {
            val anim1Size by animateDpAsState(if (anim1) 96.dp else 48.dp)

            val anim = remember { Animatable(36.dp, Dp.VectorConverter) }
            LaunchedEffect(anim2){   //只有big2的值变化了才执行该协程
//                anim.snapTo(if (big2) 128.dp else 0.dp) //不带动画
                anim.animateTo(if (anim2) 96.dp else 48.dp, spring(Spring.DampingRatioMediumBouncy))  //带动画
            }

            val anim3Transition = updateTransition(anim3)
            val anim3Size by anim3Transition.animateDp { if(it) 96.dp else 48.dp }
            val anim3CornerSize by anim3Transition.animateDp { if(it) 16.dp else 0.dp }

            val list = ArrayList<String>()
            for(i in 0..30){
                list.add("item: $i")
            }
            Column {
                Row(
                    Modifier
                        .fillMaxWidth()
                        .background(Color.Red)
                        .clickable { }
                        .padding(8.dp)){
                    Text(testText,
                        Modifier
                            .padding(6.dp)
                            .clickable { }
                            .background(Color.Blue, RoundedCornerShape(4.dp))
                            .padding(4.dp),
                        fontSize = 20.sp,
                        color = Color.White)

                    Image(painterResource(R.drawable.ic_test1),
                        "test",
                        Modifier
                            .clip(CircleShape)
                            .size(20.dp))
                    Button(onClick = { testText = "哈哈，我变了" }) {
                        Icon(painterResource(R.drawable.ic_test2),
                            "icon",
                            Modifier.size(16.dp))
                        Text("点我试试")
                    }

                    Box(
                        Modifier
                            .size(40.dp)
                            .padding(5.dp)
                            .background(Color.Gray)) {

                    }

                    Box(
                        Modifier
                            .padding(5.dp)
                            .size(40.dp)
                            .background(Color.Green)) {

                    }
                    
                }
                
                Button(onClick = {
//                    nums.add(nums.last() + 1)
                    nums[1] = 5
                    testRef++
                }) {
                    Text(text = "+1")
                }

                for (num in nums){
                    Text("这是第${num}个文字")
                }

                recomp(0, 0)
                recomp(testRef, 1)

                Row{
                    Box(
                        Modifier
                            .size(anim1Size)
                            .background(Color.Yellow)
                            .clickable { anim1 = !anim1 }){
                        Text("动画1")
                    }

                    Box(
                        Modifier
                            .size(anim.value)
                            .background(Color.Green)
                            .clickable { anim2 = !anim2 }){
                        Text("动画2")
                    }

                    Box(
                        Modifier
                            .size(anim3Size)
                            .clip(RoundedCornerShape(anim3CornerSize))
                            .background(Color.Blue)
                            .clickable { anim3 = !anim3 }){
                        Text("动画3", color = Color.White)
                    }
                }

                //自定义view
                Row(
                    Modifier
                        .fillMaxWidth()
                        .background(Color.LightGray)
                        .padding(0.dp, 10.dp)){
                    Text("绘制背景1", Modifier.drawWithContent {
                        drawRect(Color.Green)
                        drawContent()   //绘制原本内容，否则绘制的rect会把文本盖着
                    })

                    Text("绘制背景2", Modifier.drawBehind {
                        drawRect(Color.Red)
                    })

                    Text("绘制背景3", Modifier.drawWithCache {
                        val color = Color.Blue   //对color进行缓存
                        val path = Path()   //对path进行缓存
                        onDrawBehind {
                            drawRect(color)
                        }
                    })

                    Text("自定义布局1", Modifier
                        .background(Color.Green)
                        .layout { measurable, constraints ->//measurable：内部组件，不能干预内部组件的内部 constraints：对measurable进行尺寸限制
                            //自定义padding：把内部组件的尺寸加上自定义padding的尺寸作为新的尺寸
                            //设置内边距
                            val padding = 8.dp
                                .toPx()
                                .roundToInt()
                            //创建去掉padding后的限制
                            val paddedConstraints = constraints
                                .copy()
                                .apply {
                                    constrainWidth(maxWidth - padding * 2)
                                    constrainHeight(maxHeight - padding * 2)
                                }
                            //根据新的限制，对内部组件测量
                            val placeable = measurable.measure(paddedConstraints)
                            //向上汇报自己尺寸，参数为自己需要的尺寸（内部组件测量的值加上自定义的padding为自己的总数值）
                            layout(placeable.width + padding * 2, placeable.height + padding * 2) {
                                //摆放测量内部组件，参数为坐标
                                placeable.placeRelative(padding, padding)
                            }
                        }
                        .background(Color.Yellow))

                    CustomColumn(Modifier.background(Color.Magenta)){
                        Text("我是子1")
                        Text("我是子2但是我有点长")
                        Text("我是子3")
                    }
                }

                Row(Modifier.height(IntrinsicSize.Min)) {   //如果不加IntrinsicSize，Divider会撑满高度， Min/max效果一样
                    Text("看看分割线的高度")
                    Divider(
                        Modifier
                            .width(5.dp)
                            .fillMaxHeight(), color = Color.Black)
                    Text("tex\nt2")
                }

                Button(onClick = { startActivity(Intent(this@MainActivity, AndroidWithComposeActivity::class.java)) }) {
                    Text(text = "启动混合写法")
                }

                LazyColumn(
                    Modifier
                        .size(100.dp, 150.dp)
                        .background(Color.DarkGray)){
                    items(list){ item ->
                        Text(item, Modifier.clickable {  }, color = Color.White)
                    }
                }
            }
        }
    }

    @Composable
    fun recomp(abc: Int, tag: Int){
        Text("rec(${tag}): $abc")
        Log.e("fan", "我(tag:${tag})被刷新了")
    }
}

@Preview
@Composable
fun TransitionTest(){
    var anim3 by remember { mutableStateOf(false) }
    val anim3Transition = updateTransition(anim3)
    val anim3Size by anim3Transition.animateDp { if(it) 96.dp else 48.dp }
    val anim3CornerSize by anim3Transition.animateDp { if(it) 16.dp else 0.dp }
    Box(
        Modifier
            .size(anim3Size)
            .clip(RoundedCornerShape(anim3CornerSize))
            .background(Color.Blue)
            .clickable { anim3 = !anim3 }){
        Text("动画测试3", color = Color.White)
    }
}

//自定义纵向布局
//modifier: Modifier = Modifier这么写相当于有默认值，可以不传该参数
@Composable
fun CustomColumn(modifier: Modifier = Modifier, content: @Composable () -> Unit){
    Layout(content, modifier){  measurables, constraints ->
        var maxWidth = 0
        var maxHeight = 0
        //存放子组件的限制
        val placeables = mutableListOf<Placeable>()
        for ( measurable in measurables){
            //测量子组件，获取约束（）， measure只能调用1次！！！
            val placeable = measurable.measure(constraints)
            //计算最大的宽度
            maxWidth = max(maxWidth, placeable.width)
            //纵向布局，所以累加每个控件的高度
            maxHeight += placeable.height
            placeables.add(placeable)
        }
        layout(maxWidth, maxHeight) {
            var currentHeight  = 0
            //摆放每个子组件的位置
            for (placeable in placeables){
                placeable.placeRelative(0, currentHeight)
                currentHeight += placeable.height
            }
        }
    }
}
